package org.swim.web.servlet;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import org.swim.remote.entities.IAbility;
import org.swim.remote.exceptions.AbilityException;
import org.swim.remote.exceptions.SwimException;
import org.swim.remote.exceptions.SwimException.Severity;
import org.swim.remote.exceptions.TokenException;
import org.swim.remote.exceptions.UserException;
import org.swim.web.servlet.consts.Action;
import org.swim.web.utils.SwimConst;

public class AdminSL extends SwimServlet {

	private static final long serialVersionUID = 1L;
	private static String ADMIN_TOKEN;

	@Override
	protected void doRequest(HttpServletRequest request,
			HttpServletResponse response, Method method, Action action)
			throws ServletException, IOException {
		switch (action) {
		case ADMINLOGIN:
			try {
				adminLogin(request, response);
			} catch (UserException e) {
				e.printStackTrace();
				catchSwimExcpetion(action, e, "/admin?a="
						+ Action.DEFAULT.name().toLowerCase(), request,
						response);
			}
			break;
		case VIEWALLABILITIES:
			viewAllAbilities(request, response);
			break;

		case CHANGEABILITYSTATUS:
			try {
				changeAbilityStatus(request, response);
			} catch (SwimException e) {
				e.printStackTrace();
				catchSwimExcpetion(action, e, "/admin?a="
						+ Action.DEFAULT.name().toLowerCase(), request,
						response);
			}
			break;

		case ADDNEWABILITY:
			try {
				addNewAbility(request, response);
			} catch (AbilityException e) {
				e.printStackTrace();
				catchSwimExcpetion(action, e, "/admin?a="
						+ Action.DEFAULT.name().toLowerCase(), request,
						response);
			} catch (TokenException e) {
				e.printStackTrace();
				catchSwimExcpetion(action, e, "/admin?a="
						+ Action.DEFAULT.name().toLowerCase(), request,
						response);
			}
			break;

		default:
			viewAdminHome(request, response);
			break;
		}

	}

	private void addNewAbility(HttpServletRequest request,
			HttpServletResponse response) throws AbilityException,
			TokenException, IOException {

		JSONObject object = new JSONObject();
		object.accumulate("token", ADMIN_TOKEN);

		JSONObject ability = new JSONObject();
		ability.accumulate("name", request.getParameter("name"));
		object.accumulate("ability", ability);
		if(request.getParameter("name") != null && !request.getParameter("name").equals(""))
			getAmr().administratorAddAbility(object);

		response.sendRedirect(SwimConst.Url.Servlet.ADMIN + "?a="
				+ Action.VIEWALLABILITIES.name().toLowerCase());
	}

	private void changeAbilityStatus(HttpServletRequest request,
			HttpServletResponse response) throws SwimException, IOException {
		if (ADMIN_TOKEN == null || ADMIN_TOKEN.equals(""))
			throw new SwimException("Admin not logged!", Severity.ERROR);

		JSONObject object = new JSONObject();
		object.accumulate("administratorToken", ADMIN_TOKEN);
		object.accumulate("abilityId",
				Integer.parseInt(request.getParameter("abilityId")));
		object.accumulate(
				"status",
				IAbility.Status.valueOf(
						request.getParameter("status").toUpperCase())
						.name());

		getAmr().setStatusAbility(object);

		response.sendRedirect(SwimConst.Url.Servlet.ADMIN + "?a="
				+ Action.VIEWALLABILITIES.name().toLowerCase());

	}

	private void adminLogin(HttpServletRequest request,
			HttpServletResponse response) throws IOException, UserException {

		JSONObject object = new JSONObject();
		String name = request.getParameter("username");
		String password = request.getParameter("password");

		object.accumulate("name", name);
		object.accumulate("password", password);
		String token = getUmr().administratorSignIn(object);

		if (token != null)
			ADMIN_TOKEN = token;

		response.sendRedirect(SwimConst.Url.Servlet.ADMIN + "?a="
				+ Action.VIEWALLABILITIES.name().toLowerCase());
	}

	private void viewAllAbilities(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		List<IAbility> allAbility = getAmr().getAll();
		List<IAbility> confirmedAbilities = new ArrayList<IAbility>();
		List<IAbility> requestedAbilities = new ArrayList<IAbility>();
		List<IAbility> rejectedAbilities = new ArrayList<IAbility>();

		for (IAbility iAbility : allAbility) {
			switch (iAbility.getStatus()) {
			case CONFIRMED:
				confirmedAbilities.add(iAbility);
				break;
			case REJECTED:
				rejectedAbilities.add(iAbility);
				break;
			case REQUESTED:
				requestedAbilities.add(iAbility);
				break;
			}
		}

		request.setAttribute("confirmedAbilities", confirmedAbilities);
		request.setAttribute("requestedAbilities", requestedAbilities);
		request.setAttribute("rejectedAbilities", rejectedAbilities);

		request.getRequestDispatcher("adminmanager.jsp").forward(request,
				response);

	}

	private void viewAdminHome(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		request.getSession().invalidate();

		request.getRequestDispatcher("adminlogin.jsp").forward(request,
				response);
	}

}
